package com.project.core.util;

import com.project.properties.CustomProperties;
import com.common.exception.ErrCode;
import com.common.exception.SeException;
import com.aliyun.alimt20181012.Client;
import com.aliyun.alimt20181012.models.*;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.lang.Nullable;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Component
@SuppressWarnings("CallToPrintStackTrace")
public class Translate {

    @Inject
    private CustomProperties customProperties;

    // 不考虑线程安全问题
    private static Long textIndex = 0L;
    private static Long docIndex = 0L;

    private Client textClient() {
        return client(textIndex);
    }

    private Client docClient() {
        return client(docIndex);
    }

    private Client client(CustomProperties.AliTransConfig config) {
        try {
            return new Client(
                    new Config()
                            .setAccessKeyId(config.getAccessKeyId())
                            .setAccessKeySecret(config.getAccessKeySecret())
                            .setEndpoint(config.getEndpoint())
            );
        } catch (Exception e) {
            e.printStackTrace();
            throw new SeException(ErrCode.System_Error, "翻译服务端异常！");
        }
    }

    @Nullable
    private Client client(Long i) {
        if (customProperties.getAliTrans() != null && !customProperties.getAliTrans().isEmpty()) {
            long size = customProperties.getAliTrans().size();
            int index = (int) (i % size);
            CustomProperties.AliTransConfig config = customProperties.getAliTrans().get(index);
            return client(config);
        } else {
            return null;
        }
    }

    /**
     * 文本翻译
     *
     * @param sourceText 源文本
     * @return 翻译结果
     */
    public String text(String sourceText) {
        Client client = textClient();
        if (client == null) return null;
        try {
            TranslateRequest translateRequest = new TranslateRequest()
                    // 文本格式
                    .setFormatType("text")
                    // 通用翻译
                    .setScene("general")
                    // 源语言
                    .setSourceLanguage("zh")
                    // 目标语言
                    .setTargetLanguage("en")
                    // 源文本
                    .setSourceText(sourceText);
            TranslateResponse translateResponse = client.translate(translateRequest);
            if (200 == translateResponse.statusCode && 200 == translateResponse.body.code) {
                textIndex += 1;
                return translateResponse.body.data.translated;
            }
        } catch (Exception e) {
            e.printStackTrace();
            textIndex += 1;
            throw new SeException(ErrCode.System_Error, "翻译异常！");
        }
        return null;
    }

    /**
     * 文档翻译
     *
     * @param fileUrl 文件地址
     * @return 翻译结果
     */
    public String doc(String fileUrl) {
        Client client = docClient();
        if (client == null) return null;
        try {
            String clientToken = Base64.getEncoder().encodeToString(fileUrl.getBytes(StandardCharsets.UTF_8));
            CreateDocTranslateTaskRequest createDocTranslateTaskRequest = new CreateDocTranslateTaskRequest()
                    // 文件地址
                    .setFileUrl(fileUrl)
                    // 源语言
                    .setSourceLanguage("zh")
                    // 目标语言
                    .setTargetLanguage("en")
                    // 通用翻译
                    .setScene("general")
                    // 客户端唯一标识,幂等性参数,提供幂等能力，3 分钟内，相同的值只会生效一次。
                    .setClientToken(clientToken);
            RuntimeOptions runtimeOptions = new RuntimeOptions();
            CreateDocTranslateTaskResponse taskResponse = client.createDocTranslateTaskWithOptions(createDocTranslateTaskRequest, runtimeOptions);
            if (200 == taskResponse.statusCode) {
                String taskId = taskResponse.body.taskId;
                GetDocTranslateTaskRequest docTranslateTask = new GetDocTranslateTaskRequest().setTaskId(taskId);
                while (true) {
                    RuntimeOptions runtimeOptions2 = new RuntimeOptions();
                    GetDocTranslateTaskResponse taskResponse2 = null;
                    try {
                        taskResponse2 = client.getDocTranslateTaskWithOptions(docTranslateTask, runtimeOptions2);
                    } catch (Exception e) {
                        // 这里忽略异常，保证任务不会跳出
                        // 因为翻译速度任务创建可能跟不上查询速度，会报404错误，忽略即可
                    }
                    if (taskResponse2 != null && 200 == taskResponse2.statusCode) {
                        if ("translated".equals(taskResponse2.body.status)) {
                            docIndex += 1;
                            return taskResponse2.body.translateFileUrl;
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            docIndex += 1;
            throw new SeException(ErrCode.System_Error, "翻译异常！");
        }
        return null;
    }

}
